﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Timers;
using Timer = System.Timers.Timer;
namespace VIA.Project.Domain.Services
{
    public class PerformanceCaculator
    {
        Timer _timer;
        public int Count { get; private set; }
        Action<PerformanceCaculator> _callback;
        long _collectionInterval;
        public float Frequency { get; private set; }

        const long TickRate = 10_000L;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="refreshInterval">刷新间隔(单位:毫秒)</param>
        /// <param name="collectionInterval">采集间隔:单位:(毫秒)</param>
        public PerformanceCaculator(int refreshInterval, int collectionInterval, Action<PerformanceCaculator> callback)
        {
            _collectionInterval = collectionInterval;
            _timer = new Timer();
            _timer.Interval = refreshInterval;
            _timer.Elapsed += Tm_Elapsed;
            _callback = callback;
        }
        public void Restart()
        {
            _timer.Stop();
            _ticks.Clear();
            _sw.Restart();
            _timer.Start();
        }
        public void Start()
        {
            _sw.Start();
            _timer.Start();
        }
        private void Tm_Elapsed(object sender, ElapsedEventArgs e)
        {
            Update();
            _callback(this);
        }

        Queue<long> _ticks = new Queue<long>();
        //DateTime _lastTime;
        Stopwatch _sw = new Stopwatch();
        public void Tick()
        {

            var ticks = _sw.ElapsedTicks;
            _sw.Restart(); lock (this)
            {
                _ticks.Enqueue(ticks / TickRate);
            }
            Count++;

        }
        void Update()
        {
            long sum = 0;
            lock (this)
            {
                sum = _ticks.Sum();
            }
            while (sum > _collectionInterval)
            {
                _ticks.Dequeue();
                sum = _ticks.Sum();
            }
            if (_ticks.Count == 0)
            {
                Frequency = 1;
            }
            else
            {
                var interval = Math.Min(sum, _collectionInterval);
                Frequency = (float)_ticks.Count / (float)(interval) * 1000;
            }
        }
    }
}
